import bean.DiffNodeMap;
import bean.MagneticNode;
import bean.NodeDiff;
import utils.FileRecord;

import java.io.*;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

import static utils.FileRecord.writeContent;

public class DistHandler {

    private static List<MagneticNode> nodeList;
    private static List<String> fileList;
    private static String path = System.getProperty("user.dir")+"\\src" +  "\\result\\";
    private static String filePath;
    private static String fileName;
    private static int readNum;
    private static List<NodeDiff> diffList;
    private static List<DiffNodeMap> diffNodeList;

    public static void main(String[] args) throws IOException {
        nodeList = new ArrayList<>();
        fileList = new ArrayList<>();
        diffList = new ArrayList<>();
        diffNodeList = new ArrayList<>();
        Scanner in = new Scanner(System.in);
        if (getFiles(path)) {
            int n = fileList.size();
            System.out.println("请选择读取的地图文件编号");
            for (int i = 0; i < n; i++) {
                System.out.println((i + 1) + ":" + fileList.get(i));
            }
            readNum = in.nextInt();
            filePath = path + fileList.get((readNum - 1));
//            System.out.println(filePath);
            fileName = filePath.substring(0, filePath.length() - 4) + "diff.txt";
            //根据文件内容将地磁点信息存储在nodeList中
            nodeList = generateMap(filePath);
//            System.out.println(nodeList);
            //生成相邻点之间的数据差异文件
            for (int i = 0; i < nodeList.size() - 1; i++) {
                NodeDiff nodeDiff = new NodeDiff();
                int x1 = nodeList.get(i).getLocX(), x2 = nodeList.get(i + 1).getLocX();
                int y1 = nodeList.get(i).getLocY(), y2 = nodeList.get(i + 1).getLocY();
//                int diffLocX = nodeList.get(i + 1).getLocX() - nodeList.get(i).getLocX();
//                int diffLocY = nodeList.get(i + 1).getLocY() - nodeList.get(i).getLocY();
                double diffMagX = nodeList.get(i + 1).getMagX() - nodeList.get(i).getMagX();
                double diffMagY = nodeList.get(i + 1).getMagY() - nodeList.get(i).getMagY();
                double diffMagZ = nodeList.get(i + 1).getMagZ() - nodeList.get(i).getMagZ();
                nodeDiff.setX1(x1);
                nodeDiff.setX2(x2);
                nodeDiff.setY1(y1);
                nodeDiff.setY2(y2);
                nodeDiff.setMagX(Math.round(diffMagX * 100) / 100);
                nodeDiff.setMagY(Math.round(diffMagY * 100) / 100);
                nodeDiff.setMagZ(Math.round(diffMagZ * 100) / 100);
                diffList.add(nodeDiff);
            }
            System.out.println(diffList);
            if (FileRecord.createFile(fileName)) {
                int k = diffList.size();
                for (int i = 0; i < k; i++) {
                    String content = "(" + diffList.get(i).getX1() + "," + diffList.get(i).getY1() + ")" +
                            "(" + diffList.get(i).getX2() + "," + diffList.get(i).getY2() + ")" +
                            "->" + diffList.get(i).getMagX() + ","
                            + diffList.get(i).getMagY() + diffList.get(i).getMagZ();
                    writeContent(content, fileName);
                }
            }

            //生成单一点到其他各个点的数据差异文件
            n = nodeList.size();
            DecimalFormat df = new DecimalFormat("######0.00");
            String distNode[][] = new String[n][n];
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    distNode[i][j] = "0";
                }
            }
            for (int i = 0; i < n; i++) {
                double diffX;
                double diffY;
                double diffZ;
                for (int j = i + 1; j < n; j++) {
                    diffX = nodeList.get(j).getMagX() - nodeList.get(i).getMagX();
                    diffY = nodeList.get(j).getMagY() - nodeList.get(i).getMagY();
                    diffZ = nodeList.get(j).getMagZ() - nodeList.get(i).getMagZ();
                    double dist = Math.sqrt(diffX * diffX + diffY* diffY + diffZ * diffZ);
                    distNode[i][j] = df.format(dist);
                }

                for (int j = 0; j < i; j++) {
                    distNode[i][j] = distNode[j][i];
                }

                DiffNodeMap map = new DiffNodeMap();
                map.setX(nodeList.get(i).getLocX());
                map.setY(nodeList.get(i).getLocY());
                map.setDist(distNode[i]);
                diffNodeList.add(map);
            }
            //生成例如2019-8-15 16-27-23diffMap.txt的误差值文件
            String diffFile = path + FilesHandler.getTime() + "diffMap.txt";
            for (int i = 0; i < diffNodeList.size(); i++) {
                System.out.println(diffNodeList.get(i).toString());
                writeContent(Arrays.toString(diffNodeList.get(i).getDist()), diffFile);
            }

            System.out.println("Please type in the true x,y,z data");
            //获取输入的xyz轴数据与其他各个点的地磁指纹数据的距离
            double getX = in.nextDouble();
            double getY = in.nextDouble();
            double getZ = in.nextDouble();
            double dist[] = new double[n];
            for (int i = 0; i < n; i++) {
                double diffX = getX - nodeList.get(i).getMagX();
                double diffY = getY - nodeList.get(i).getMagY();
                double diffZ = getZ - nodeList.get(i).getMagZ();
                dist[i] = Math.sqrt(diffX * diffX + diffY* diffY + diffZ * diffZ);
            }
            //将获取到的dist[]数组与误差值文件中的数组进行对比，看与哪个指纹点的数据最相似
            double sum[] = new double[n];
            for (int i = 0; i < n; i++) {
                double lineSum = 0;
                String fileDist[] = diffNodeList.get(i).getDist();
                int m = fileDist.length;
                for (int j = 0; j < m; j++) {
                    double diff = (dist[j] - Double.parseDouble(fileDist[j]))
                            * (dist[j] - Double.parseDouble(fileDist[j]));
                    lineSum = lineSum + diff;
                }
                sum[i] = Math.sqrt(lineSum);
            }
            System.out.println(Arrays.toString(sum));
            double min = sum[0];
            int flag = 0;
            for (int i = 0; i < n; i++) {
                if (min > sum[i]) {
                    min = sum[i];
                    flag = i;
                }
            }
            System.out.println(nodeList.get(flag).toString());


        } else {
            System.out.println("没有获取到地图文件");
        }
    }

    /**
     * 读取磁场地图文件
     * @param filePath 文件路径
     * @return string字符串
     */
    public static List<MagneticNode> generateMap(String filePath){
        List<MagneticNode> nodeList = new ArrayList<>();
        try {
            String encoding="UTF-8";
            File file=new File(filePath);
            if(file.isFile() && file.exists()){ //判断文件是否存在
                InputStreamReader read = new InputStreamReader(new FileInputStream(file),encoding);//考虑到编码格式
                BufferedReader bufferedReader = new BufferedReader(read);
                String lineTxt;
                while((lineTxt = bufferedReader.readLine()) != null){
                    String getDetails[] = lineTxt.split(",");
                    MagneticNode node = new MagneticNode();
                    node.setLocX(Integer.parseInt(getDetails[0]));
                    node.setLocY(Integer.parseInt(getDetails[1]));
                    node.setMagX(Double.parseDouble(getDetails[2]));
                    node.setMagY(Double.parseDouble(getDetails[3]));
                    node.setMagZ(Double.parseDouble(getDetails[4]));
                    nodeList.add(node);
                }
                read.close();
            } else {
                System.out.println("找不到指定的文件");
            }
        } catch (Exception e) {
            System.out.println("读取文件内容出错");
            e.printStackTrace();
        }
        return nodeList;
    }

    private static boolean getFiles(String path) {
        File file = new File(path);
        File[] fileArray = file.listFiles();
        for (File aFileArray : fileArray) {
            if (aFileArray.toString().endsWith(".txt") && aFileArray.isFile()) {
                fileList.add(aFileArray.getName());
            }
        }
        return fileList.size() > 0;
    }
}
